package paint2.infraestructura;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import paint2.modelo.Circulo;
import paint2.modelo.Figura;
import paint2.modelo.Linea;
import paint2.modelo.Punto;
import paint2.modelo.Rectangulo;
import paint2.ui.ventanas.Mensaje;

public class PersistenciaDeFigurasEnBD implements Persistencia {

    private Set<Figura> figuras = new HashSet();
    private final String url = "jdbc:mysql://localhost:3306/MP2";
    private final String usuario = "root";
    private final String clave = "";
    private Connection connection = null;
    private Statement queryDeDibujo = null;
    private ResultSet figura = null;

    public Set<Figura> obtenerElementos(String nombreDeDibujo) {

        try {
            connection = DriverManager.getConnection(url, usuario, clave);
            queryDeDibujo = connection.createStatement();
            figura = queryDeDibujo.executeQuery("SELECT * FROM figuras where Figura_Nombre = '" + nombreDeDibujo + "';");

            creaTodasLasFigurasDelDibujo();

        } catch (SQLException ex) {
        } finally {
            if (figura != null) {
                try {
                    figura.close();
                } catch (SQLException ex) {
                }
            }
            if (queryDeDibujo != null) {
                try {
                    queryDeDibujo.close();
                } catch (SQLException ex) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException ex) {
                }
            }
        }
        return figuras;
    }

    private void creaTodasLasFigurasDelDibujo() throws SQLException {
        while (figura.next()) {
            final String tipo = figura.getString("Figura_Tipo");
            siLaFiguraEsUnaLineaLaCrea(tipo, figura);
            siLaFiguraEsUnRectanguloLoCrea(tipo, figura);
            siLaFiguraEsUnCirculoLoCrea(tipo, figura);
        }
    }

    private boolean existeAlgunaFiguraEn() {
        return figura != null;
    }

    private void siLaFiguraEsUnCirculoLoCrea(final String tipo, ResultSet figura) throws SQLException {
        if (laFiguraEsUnCirculo(tipo)) {
            Circulo circulo = new Circulo();
            circulo.setInicio(new Punto((float) figura.getInt("Figura_Punto_Inicio_X"), (float) figura.getInt("Figura_Punto_Inicio_Y")));
            circulo.setFin(new Punto((float) figura.getInt("Figura_Punto_Fin_X"), (float) figura.getInt("Figura_Punto_Fin_Y")));
            this.figuras.add(circulo);
        }
    }

    private void siLaFiguraEsUnRectanguloLoCrea(final String tipo, ResultSet figura) throws SQLException {
        if (laFiguraEsUnRectangulo(tipo)) {
            Rectangulo rectangulo = new Rectangulo();
            rectangulo.setInicio(new Punto((float) figura.getInt("Figura_Punto_Inicio_X"), (float) figura.getInt("Figura_Punto_Inicio_Y")));
            rectangulo.setFin(new Punto((float) figura.getInt("Figura_Punto_Fin_X"), (float) figura.getInt("Figura_Punto_Fin_Y")));
            this.figuras.add(rectangulo);
        }
    }

    private void siLaFiguraEsUnaLineaLaCrea(final String tipo, ResultSet figura) throws SQLException {
        if (laFiguraEsUnaLinea(tipo)) {
            Linea linea = new Linea();
            linea.setInicio(new Punto((float) figura.getInt("Figura_Punto_Inicio_X"), (float) figura.getInt("Figura_Punto_Inicio_Y")));
            linea.setFin(new Punto((float) figura.getInt("Figura_Punto_Fin_X"), (float) figura.getInt("Figura_Punto_Fin_Y")));
            this.figuras.add(linea);
        }
    }

    private boolean laFiguraEsUnCirculo(final String tipo) {
        return ("Circulo").equals(tipo);
    }

    private boolean laFiguraEsUnRectangulo(final String tipo) {
        return ("Rectangulo").equals(tipo);
    }

    private boolean laFiguraEsUnaLinea(final String tipo) {
        return ("Linea").equals(tipo);
    }

    public void guardarElementos(Set<Figura> figuras, String nombreDeDibujo) {
        try {
            this.connection = DriverManager.getConnection(url, usuario, clave);
            this.queryDeDibujo = connection.createStatement();

            for (Figura unaFigura : figuras) {
                queryDeDibujo.executeUpdate("INSERT INTO figuras"
                        + "(Figura_Nombre,Figura_Tipo,Figura_Punto_Inicio_X,Figura_Punto_Inicio_Y,Figura_Punto_Fin_X,Figura_Punto_Fin_Y) VALUES"
                        + "('" + nombreDeDibujo + "','" + unaFigura.tipo() + "'," + unaFigura.inicio().x() + "," + unaFigura.inicio().y() + "," + unaFigura.fin().x() + "," + unaFigura.fin().y() + ");");
            }

            Mensaje.mostrar("Guardar", "El archivo se ha guardado correctamente");

        } catch (SQLException ex) {
            Mensaje.mostrar("Error", "Ha ocurrido un error guardando el dibujo.");
        } finally {
            if (queryDeDibujo != null) {
                try {
                    queryDeDibujo.close();
                } catch (SQLException ex) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException ex) {
                }
            }
        }
    }

    public boolean existeElDibujo(String nombreDeDibujo) {
        try {
            connection = DriverManager.getConnection(url, usuario, clave);
            queryDeDibujo = connection.createStatement();
            figura = queryDeDibujo.executeQuery("SELECT * FROM figuras where Figura_Nombre = '" + nombreDeDibujo + "';");

            while (figura.next()) {
                return true;
            }
            return false;

        } catch (SQLException ex) {
        } finally {
            if (figura != null) {
                try {
                    figura.close();
                } catch (SQLException ex) {
                }
            }
            if (queryDeDibujo != null) {
                try {
                    queryDeDibujo.close();
                } catch (SQLException ex) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException ex) {
                }
            }
        }
        return false;
    }

    public Object[] nombreDeDibujos() {

        List<String> nombres = new ArrayList();

        try {
            connection = DriverManager.getConnection(url, usuario, clave);
            queryDeDibujo = connection.createStatement();
            figura = queryDeDibujo.executeQuery("SELECT distinct Figura_Nombre FROM figuras;");

            while (figura.next()) {
                nombres.add(figura.getString("Figura_Nombre"));
            }

        } catch (SQLException ex) {
        } finally {
            if (figura != null) {
                try {
                    figura.close();
                } catch (SQLException ex) {
                }
            }
            if (queryDeDibujo != null) {
                try {
                    queryDeDibujo.close();
                } catch (SQLException ex) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException ex) {
                }
            }
        }
        return nombres.toArray();
    }

    public void borrar(String nombreDeDibujo) {

        try {
            this.connection = DriverManager.getConnection(url, usuario, clave);
            this.queryDeDibujo = connection.createStatement();

            queryDeDibujo.executeUpdate("DELETE FROM figuras WHERE Figura_Nombre = '" + nombreDeDibujo + "';");

        } catch (SQLException ex) {
            ex.printStackTrace();
            Mensaje.mostrar("Error", "Ha ocurrido un error borrando el dibujo.");
        } finally {
            if (queryDeDibujo != null) {
                try {
                    queryDeDibujo.close();
                } catch (SQLException ex) {
                }
            }
            if (connection != null) {
                try {
                    connection.close();
                } catch (SQLException ex) {
                }
            }
        }
    }
}
